/*
 * Tezad - Classic puzzle game
 * Copyright 2009 Shayne Riley and Paul Maseberg
 *
 * Tezad is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Tezad is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Tezad.  If not, see <http://www.gnu.org/licenses/>
 * or write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * To contact the authors on questions or issues regarding the license,
 * you may send an email to <pezads at gmail dot com>
 */


#ifndef GAMEWELL_H_
#define GAMEWELL_H_

#include <stdexcept>

/**
 * Concrete class for the well which contains all the tetromino bricks.
 *
 * - Rows start at 0 and go from the bottom-up, unlike how most standard
 *   C++ arrays are represented (top-down).
 * - Columns start at 0 and are standard left-right.
 * - Each brick is represented as an int, although this will change later.
 */
class GameWell
{
public:
    /**
     * The primary constructor.
     * @param height  The complete number of rows, including hidden rows.
     * Must be positive, or an out_of_range exception will be thrown.
     * @param width  The complete number of columns.
     * Must not be positive, or an out_of_range exception will be thrown.
     * @param hiddenHeight The number of rows on top not to be displayed.
     * Must not be negative or greater than height, or an out_of_range
     * exception will be thrown.
     */
    GameWell(int totalHeight, int width, int hiddenHeight);

    /**
     * Copy constructor.
     * @param src   Copies from this object.
     */
    GameWell(const GameWell& src);

    ~GameWell();

    /**
     * Assignment operator.
     * @param rhs   Right-hand side of the operator. Copy from this object.
     * @return Reference to this object.
     */
    GameWell& operator=(const GameWell& rhs);

    /// @returns a positive number that is the horizontal dimension.
    int width() const;

    /// @returns a positive number that is the complete vertical dimension.
    int height() const;

    /// @returns a positive number that is only the height that can be seen.
    int visibleHeight() const;

    /**
     * Get the brick of a tetromino at a certain location of the well.
     * @param row  the vertical position to grab the brick. 0 is at the bottom.
     * An out_of_range exception will be thrown if the position is less than 0
     * or greater than height.
     * @param col  the horizonal position to grab the brick. 0 is at the left.
     * An out_of_range exception will be thrown if the position is less than 0
     * or greater than width.
     *
     * @returns 0 for unoccupied space, or any other integer if it is occupied.
     */
    int brick(int row, int col) const;

    /**
     * Set the brick in a location of the well.
     * @param row   The vertical coordinate of the brick. 0 is at the bottom.
     * @param col   The horizontal coordinate of the brick. 0 is at the left.
     * @param inBrick The value of the brick. 0 is empty, any other number is
     *  filled.
     */
    void setBrick(int row, int col, int inBrick);

    /**
     * Clears out a row and drops the upper rows to fill the void.
     * @param row   The vertical coordinate of the brick. 0 is at the bottom.
     */
    void clearRow(int row);

private:
    int mHeight;
    int mWidth;
    int mHiddenHeight;
    int *mWell;
};

#endif /* GAMEWELL_H_ */
